/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
 * Description: Cast session wifi display class.
 * Create: 2024-5
 */

#ifndef CAST_SESSION_WIFI_DISPLAY_H
#define CAST_SESSION_WIFI_DISPLAY_H

#include "i_cast_session_listener_impl.h"
#include "cast_session_impl_stub.h"
#include "cast_engine_common.h"
#include "cast_session_common.h"
#include "cast_session_enums.h"
#include "wifi_display_manager.h"

#include <mutex>
#include <memory>
#include <list>
#include <map>


namespace OHOS {
namespace CastEngine {
namespace CastEngineService {

class CastSessionWifiDisplay : public CastSessionImplStub,
    public std::enable_shared_from_this<CastSessionWifiDisplay> {
public:
    CastSessionWifiDisplay(const CastSessionProperty &property, const CastLocalDevice &localDevice);
    ~CastSessionWifiDisplay() override;
    void SetServiceCallbackForRelease(const std::function<void(int)> &callback);
    int32_t RegisterListener(sptr<ICastSessionListenerImpl> listener) override;
    int32_t UnregisterListener() override;
    int32_t AddDevice(const CastRemoteDevice &remoteDevice) override;
    int32_t RemoveDevice(const std::string &deviceId) override;
    int32_t StartAuth(const AuthInfo &authInfo) override;
    int32_t GetSessionId(std::string &sessionId) override;
    int32_t GetDeviceState(const std::string &deviceId, DeviceState &deviceState) override;
    int32_t SetSessionProperty(const CastSessionProperty &property) override;
    int32_t CreateMirrorPlayer(sptr<IMirrorPlayerImpl> &mirrorPlayer) override;
    int32_t CreateStreamPlayer(sptr<IStreamPlayerIpc> &streamPlayer) override;
    int32_t Release() override;
    int32_t NotifyEvent(EventId eventId, std::string &jsonParam) override;
    int32_t SetCastMode(CastMode mode, std::string &jsonParam) override;
    int32_t SetAudioOutput(EndType type) override;
    int32_t GetSessionProtocolType(ProtocolType &protocolType) override;
    int32_t AcceptDeviceConnection(const std::string &deviceId, bool accept) override;
    void SetSessionProtocolType(ProtocolType protocolType) override;
    void OnConnectionChanged(DeviceState state, const std::string &deviceId, const std::string &deviceName);
    void OnConnectionError(DeviceState state, const std::string &deviceId, int32_t errCode);
    void OnDeviceRequest(const std::vector<CastRemoteDevice> &deviceList);
    bool Init(int32_t sessionId);
    int32_t SetCastRoute(const bool &remote);

    int32_t Play(const std::string &deviceId) override;
    int32_t Pause(const std::string &deviceId) override;
    int32_t SetSurface(sptr<IBufferProducer> producer) override;
    int32_t DestroyMirrorPlayer() override;
    int32_t GetDisplayId(std::string &displayId) override;
    int32_t ResizeVirtualScreen(uint32_t width, uint32_t height) override;
    int32_t DeliverInputEvent(const OHRemoteControlEvent &event) override;
    int32_t InjectEvent(const OHRemoteControlEvent &event) override;

private:
    std::shared_ptr<CastRemoteDeviceInfo> FindRemoteDevice(const std::string &deviceId);
    std::shared_ptr<CastRemoteDeviceInfo> FindRemoteDeviceLocked(const std::string &deviceId);
    void RemoveRemoteDevice(const std::string &deviceId);
    void UpdateRemoteDeviceId(const std::string &deviceId, const std::string &deviceName);
    bool AddRemoteDevice(const CastRemoteDeviceInfo &remoteDeviceInfo);
    bool AddDeviceInner(const CastInnerRemoteDevice &remoteDevice) override;

    sptr<IMirrorPlayerImpl> MirrorPlayerGetter();
    template<class T>
    std::string CreateParamter(const std::string &Key, T value);

    class CastSessionWfdEventListener : public Sharing::IWfdEventListener
    {
    public:
        explicit CastSessionWfdEventListener(CastSessionWifiDisplay *sessionWifiDisplay);

        void OnInfo(std::shared_ptr<Sharing::BaseMsg> &msg) override;

    private:
        CastSessionWifiDisplay *sessionWifiDisplay_{ nullptr };
    };

    int32_t uicastAppUid_{ -1 };
    std::mutex serviceCallbackMutex_;
    std::function<void(int)> serviceCallback_;
    std::map<pid_t, sptr<ICastSessionListenerImpl>> listeners_;
    int sessionId_{ -1 };
    std::list<CastRemoteDeviceInfo> remoteDeviceList_;
    CastLocalDevice localDevice_;
    CastSessionProperty property_;
    std::mutex mutex_;
    static constexpr int MAX_SESSION_ID = 0xFFFFFFF;
    inline static const std::string KEY_AUDIO = "audio";
    sptr<IMirrorPlayerImpl> mirrorPlayer_;
    std::string acceptDeviceId_;
    std::shared_ptr<CastSessionWfdEventListener> wfdEventListener_;
    uint64_t surfaceId_ = 0;
    friend class CastSessionWfdEventListener;
};
} // namespace CastEngineService
} // namespace CastEngine
} // namespace OHOS

#endif
